package com.apkcore.core.ui.recyclerview

import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding

abstract class RVAdapter<T, VB : ViewBinding>(
    private val inflate: (LayoutInflater, ViewGroup, Boolean) -> VB
) : RecyclerView.Adapter<RVAdapter.BaseViewHolder<VB>>() {

    private val items: MutableList<T> = mutableListOf()
    private val cacheItems: MutableList<T> = mutableListOf()
    private var itemClickListener: ((View, Int, T) -> Unit)? = null
    private var itemLongClickListener: ((View, Int, T) -> Unit)? = null
    private var filterAction: ((T) -> Boolean)? = null

    abstract fun bind(binding: VB, item: T, position: Int)
    open fun initView(binding: VB, itemView: View) {}

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<VB> {
        val binding = inflate(LayoutInflater.from(parent.context), parent, false)
        val viewHolder = BaseViewHolder(binding)
        initView(binding, viewHolder.itemView)
        itemClickListener?.let {
            viewHolder.itemView.setOnClickListener { view ->
                val position = viewHolder.adapterPosition
                if (position != RecyclerView.NO_POSITION) {
                    it.invoke(view, position, items[position])
                }
            }
        }
        itemLongClickListener?.let {
            viewHolder.itemView.setOnLongClickListener { view ->
                val position = viewHolder.adapterPosition
                if (position != RecyclerView.NO_POSITION) {
                    it.invoke(view, position, items[position])
                    return@setOnLongClickListener true
                }
                false
            }
        }
        return viewHolder
    }

    override fun onBindViewHolder(holder: BaseViewHolder<VB>, position: Int) {
        bind(holder.binding, items[position], position)
    }

    override fun getItemCount(): Int = items.size

    @SuppressLint("NotifyDataSetChanged")
    fun setItems(newItems: List<T>) {
        cacheItems.clear()
        cacheItems.addAll(newItems)
//        items.clear()
//        items.addAll(newItems)
        adapterAddList(cacheItems)
    }

    fun clearList() {
        cacheItems.clear()
        items.clear()
        notifyDataSetChanged()
    }

    fun filterItems(
        filterFinished: (() -> Unit)? = null,
        filterAction: (item: T) -> Boolean
    ) {
        if (cacheItems.isEmpty()) {
            cacheItems.addAll(items)
        }
        this.filterAction = filterAction
        adapterAddList(cacheItems)
        filterFinished?.invoke()
    }

    private fun adapterAddList(cacheItems: List<T>) {
        val list = filterAction?.let { filter ->
            cacheItems.filter { filter(it) }.toMutableList()
        } ?: run {
            cacheItems
        }
        val count = items.size
        if (count > 0) {
            items.clear()
            notifyItemRangeRemoved(0, count)
        }
        items.addAll(list)
        notifyItemRangeInserted(0, items.size)
    }

    fun addItem(
        item: T,
        index: Int = items.size,
    ): Int {
        var ind = index
        ind = ind.coerceIn(0, items.size)
        cacheItems.add(ind, item)
        if (filterAction == null || filterAction?.invoke(item) == true) {
            items.add(ind, item)
            notifyItemRangeInserted(ind, items.size - ind)
            return ind
        }
        return -1
    }

    fun setOnItemClickListener(listener: (view: View, position: Int, item: T) -> Unit) {
        itemClickListener = listener
    }

    fun setOnItemLongClickListener(listener: (view: View, position: Int, item: T) -> Unit) {
        itemLongClickListener = listener
    }

    class BaseViewHolder<VB : ViewBinding>(val binding: VB) :
        RecyclerView.ViewHolder(binding.root)
}
